package com.tza.web.t_net.server;

import java.io.OutputStream;

import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

import com.google.gwt.rpc.server.ClientOracle;
import com.google.gwt.rpc.server.RPC;
import com.google.gwt.rpc.server.RpcServlet;
import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.server.rpc.RPCRequest;

/**
 * Dispatching servlet for screen services. The bean name is retrieved thanks to
 * the url called (*.rpc). Screen services are instantiated with Spring
 */
public class RPCServletDispatcher extends RpcServlet
{
   private static final long serialVersionUID = 6581897620642379453L;

   ClassPathResource         res              = new ClassPathResource("applicationContext.xml");
   XmlBeanFactory            factory          = new XmlBeanFactory(res);

   // Thread is start with the server startup
   public RPCServletDispatcher()
   {
      super();

      // // Init du context spring
      // ApplicationContext context =
      // ContextLoader.getCurrentWebApplicationContext();
      // new SpringApplicationContextFactory(context);

   }

   @Override
   public void processCall(ClientOracle clientOracle, String payload, OutputStream stream) throws SerializationException
   {
      try
      {
         String beanName = extractBeanName(getThreadLocalRequest().getServletPath());
         if (beanName == null)
         {

            throw new Exception("Service beanid was not retrieved : " + getThreadLocalRequest().getServletPath());
         }
         Object beanSpring = factory.getBean(beanName);
         RPCRequest rpcRequest = RPC.decodeRequest(payload, beanSpring.getClass(), clientOracle);

         onAfterRequestDeserialized(rpcRequest);

         RPC.invokeAndStreamResponse(beanSpring, rpcRequest.getMethod(), rpcRequest.getParameters(), clientOracle, stream);
      }
      catch (Exception e)
      {

         throw new SerializationException(e);
      }
   }

   /**
    * Private method to substring the beanid of the url servlet Path
    * 
    * @param ServletPath
    * @return Service beanid
    */
   private String extractBeanName(String servletPath)
   {
      if (servletPath == null)
      {
         return null;
      }
      try
      {
         return servletPath.substring(servletPath.indexOf('/', 1) + 1).replaceAll(".rpc", "");
      }
      catch (Exception e)
      {
         return null;
      }
   }

}
